--
-- @Author:      name
-- @DateTime:    2018-03-30 23:05:48
-- @Description: 机器人逻辑

local skynet = require "skynet"
local json = require "cjson"
local log = require "Log"
local Network = require "Network"
local roomConfig = require "lua_PdkTableList"
local NodeMessage = require "NodeMessage"
require "setting"
local Ai = require "Ai"

local Logic = class("Logic")

---------------------------------------------------------
-- Private
---------------------------------------------------------
function Logic:ctor(data,player)
	--随机种子
    local time = tostring(os.time())
    math.randomseed(time:reverse():sub(1, 7))
	local svr_config = robot_setting['paohuzi']
	self.playerid = player.uid
	self.player = player
	if not player then 
		self.playerid = data.mid
	end
	self.ip = svr_config.ip
	self.port = svr_config.port		
	self.tbConf = {} --场次配置
	self.roomid = data.roomid
	self.tableid = data.tableid
	if not self.roomid then 
		self.roomid = data.type
	end
	for _,v in pairs(roomConfig) do 
		table.insert(self.tbConf,v)
	end
	table.sort(self.tbConf,function (a,b)
		if a.min_coin < b.min_coin then 
			return true
		end
	end)
	self.roomConf = self.tbConf[self.roomid] --要入的场
	self.onlineTime = 0
	self.ExitTime = math.random(10,30) * 60
	self.playingTime = 0
	self.leaveTableTime = math.random(3,9) * 60
	self.printPlayerId = 1201158
	self.myDealCards = {}
	self.curCards = nil
	self.cardSeatid = nil --桌子上的牌是谁的
	self.nodeMessage = NodeMessage.new()
	--开启网络模块
	print("__svr_config__",svr_config)
	self.network = Network.new(self.ip,self.port)
	-- self.ai = Ai.new()
	self.kan = {}
print("___data__",data)
	self.curCard = nil --当前摸或出牌
	--注册消息回调
	self:register()

	self:login(self.playerid)
	self:closeByTime()
end

function Logic:register()
	self.network:register('socket_close',handler(self,self.socketClose))
	self.network:register('heart_res',handler(self,self.heart_res))
	self.network:register('login_res',handler(self,self.login_res))
	self.network:register('php_res',handler(self,self.php_res))
	self.network:register('logout_res',handler(self,self.logout_res))
	self.network:register('room_state_res',handler(self,self.room_state_res))
	self.network:register('enter_table_res',handler(self,self.enter_table_res))
	self.network:register('leave_table_res',handler(self,self.leave_table_res))	
	self.network:register('changetable_res',handler(self,self.changetable_res))		
	self.network:register('reconnect_res',handler(self,self.reconnect_res))
	self.network:register('nt_broadcast',handler(self,self.nt_broadcast))
	self.network:register('nt_goods_change',handler(self,self.nt_goods_change))
	self.network:register('nt_enter_gate',handler(self,self.nt_enter_gate))
	self.network:register('nt_kick_table',handler(self,self.nt_kick_table))
	self.network:register('sitdown_res',handler(self,self.sitdown_res))
	self.network:register('standup_res',handler(self,self.standup_res))
	self.network:register('exit',handler(self,self.exit))
	self.network:register('nt_chat',handler(self,self.nt_chat))
	self.network:register('createtable_res',handler(self,self.createtable_res))

	self.network:register('enterprivate_res',handler(self,self.enterprivate_res))


	self.network:register('phz_nt_seat_change',handler(self,self.phz_nt_seat_change))	
	self.network:register('phz_nt_rest',handler(self,self.phz_nt_rest))
	self.network:register('phz_nt_start',handler(self,self.phz_nt_start))
	self.network:register('phz_nt_oper',handler(self,self.phz_nt_oper))	
	self.network:register('phz_nt_end',handler(self,self.phz_nt_end))
	self.network:register('phz_nt_zhadan',handler(self,self.phz_nt_zhadan))
	self.network:register('nt_manager_close',handler(self,self.nt_manager_close))


	self.network:register('phz_status_res',handler(self,self.phz_status_res))
	self.network:register('phz_deal_res',handler(self,self.phz_deal_res))
	self.network:register('phz_tip_res',handler(self,self.phz_tip_res))
	self.network:register('phz_next_res',handler(self,self.phz_next_res))		
	self.network:register('phz_ready_res',handler(self,self.phz_ready_res))		
	self.network:register('phz_close_vote_res',handler(self,self.phz_close_vote_res))	
	self.network:register('phz_nt_close_vote',handler(self,self.phz_nt_close_vote))		
	self.network:register('phz_nt_fanka_end',handler(self,self.phz_nt_fanka_end))	

	self.network:register('phz_nt_turn_seat',handler(self,self.phz_nt_turn_seat))
	self.network:register('phz_nt_play_card',handler(self,self.phz_nt_play_card))

	self.network:register('phz_nt_can_reponse',handler(self,self.phz_nt_can_reponse))
	self.network:register('phz_nt_take_card',handler(self,self.phz_nt_take_card))
	self.network:register('phz_nt_confirm_card',handler(self,self.phz_nt_confirm_card))
	self.network:register('phz_nt_peng',handler(self,self.phz_nt_peng))
	self.network:register('phz_nt_pao',handler(self,self.phz_nt_pao))
	self.network:register('phz_nt_wei',handler(self,self.phz_nt_wei))
	self.network:register('phz_nt_chi',handler(self,self.phz_nt_chi))
	self.network:register('phz_nt_ti',handler(self,self.phz_nt_ti))

	self.network:register('phz_peng_res',handler(self,self.phz_peng_res))
	self.network:register('phz_chi_res',handler(self,self.phz_chi_res))

end

function Logic:print(...)
	-- if self.playerid ~= self.printPlayerId then 
	-- 	return 
	-- end
	print(...)
end

function Logic:socketClose()
	skynet.exit()
end

function Logic:exit()
	skynet.sleep(100)
	self.network:close()
	skynet.exit()
end

function Logic:showError(data)
	if data.err_no and data.err_no > 0 then 
		print("_____error__",data)
		-- self:exit()
		return false
	end
	return true
end

function Logic:get_all_value_nums(cards)
	local ret = {}
	for _,v in pairs(cards) do
		if ret[v] then
			ret[v] = ret[v] + 1
		else
			ret[v] = 1
		end
	end
	return ret
end
function Logic:drop(t,c)
	for i,v in ipairs(t) do
		if v == c then
			table.remove(t,i)
			return true
		end
	end
end
function Logic:arrange_set(cards)	
	--把坎牌放到坎牌区
	local card_nums = self:get_all_value_nums(cards)
	for k,v in pairs(card_nums) do
		if v == 3 then
			self:drop(cards,k)
			self:drop(cards,k)
			self:drop(cards,k)
			table.insert(self.kan,{k,k,k})
		end
	end
end



--账号
function Logic:login(mid)
	local str = '{"ver":"1.0.0","appid":10100100,"action":"user.guestLogin","platform":1,"cmd":10000}'
	if mid then 
		str = '{"ver":"1.0.0","appid":10100100,"mid":'..mid..',"action":"user.guestLogin","platform":1,"cmd":10001}'
	end

	-- local data = {php_req={
	-- 	id = 10002,
	-- 	content = str,
	-- }}
	local data = {login_req={
 		playerid = mid,
 		key = 'key',
	}}
	self.network:send(data)
end


local num = 0
function Logic:php_res(data)
	-- self:print("___php_res",data)
	if not self:showError(data) then 
		return 
	end


	-- num = num + 1
	-- if num > 1 then 
	-- 	return
	-- end
	-- self:logout_req()
end

function Logic:login_res(data)

end

function Logic:nt_enter_gate(data)
	print("_________nt_enter_gate___",data)
	--进入大厅成功
	local delay = math.random(100,300)
	skynet.sleep(delay)
	-- self.nodeMessage:sendService('manager','rb_nt_online',data)
	local sql = string.format("select * from usergame where uid = %d", self.playerid)
	local res = skynet.call("mysql_service", "lua", "execute", sql)
	if res and next(res) then
		res = res[1]
		self.player = res
	end
	--进入场次
	--1对入场金币进行判断
	local sql = string.format("select * from common_room where sub_id = %d", self.roomid)
	local res = skynet.call("mysql_service", "lua", "execute", sql)
	if res and next(res) then 
		res = res[1]
		print("_____nt_enter_gate_______",self.player.uchip , res.min_money,res.max_money)
		if self.player.uchip < res.min_money then 
			local money = res.min_money - self.player.uchip + math.random(500,1000)
			local data =  {money = money, uid = self.playerid, game = 4, gameid = 104, code = 0, gametype = 0}
			skynet.call("manager", "lua", "change_money", data)
			self:login(self.playerid)
			return 
		elseif self.player.uchip > res.max_money then 
			local money = res.max_money - self.player.uchip - math.random(1000,2000)
			local data =  {money = money, uid = self.playerid, game = 4, gameid = 104, code = 0, gametype = 0}
			skynet.call("manager", "lua", "change_money", data)			
			self:login(self.playerid)
			return 			
		end
	end

	self:enterTable(self.roomid)

	local tb = {
		jushu=1,
		card_num=1,
		chip=1,		
		payer=1,
		roomType=1,
	}
	local str = json.encode(tb)
	local data = {createtable_req={gameid=4,setting=str,type=1}}
	-- self.network:send(data)


	local data = {enterprivate_req={tablenum=113201,gameid=4}}
	-- self.network:send(data)

end

--登出
function Logic:logout_req()
	local data = {logout_req={playerid=1}}
	self.network:send(data)
end
function Logic:logout_res(data)
	if not self:showError(data) then 
		return 
	end
	self:login(self.playerid)
end

--场次信息
function Logic:room_state_req(gameid)
	local data = {room_state_req={
 		gameid=gameid, 	
	}}
	self:print(data)
	self.network:send(data)
end
function Logic:room_state_res(data)

end

function Logic:enterTable(room_type)
	local data = {enter_table_req={
 		-- room_type=room_type, 	
 		tableid = self.tableid,
	}}
	self.network:send(data)		
end
function Logic:enter_table_res(data)
	print("_____enter_table_res___",data)
	-- if not self:showError(data) then 
	-- 	return 
	-- end
	-- self:print("____enter_table____",data)
	-- if data.err_no and data.err_no > 0 then 
	-- 	if data.err_no == 12 then 
	-- 		self:print("____________金币不足___",self.playerid,self.robotType)
	-- 		data = {playerid=self.playerid,robotType=self.robotType}
	-- 		self.nodeMessage:sendService('manager','change_money',data)
	-- 		self:exit()
	-- 		return 
	-- 	elseif data.err_no then 
	-- 		self:exit() 
	-- 		return
	-- 	end
	-- end
	if data.tableid > 0 then 
		self.tableid = self.tableid --data.tableid
		self:statusReq()
	else
		self:exit()
	end
	--self:reconnect_req()
	
end

function Logic:reconnect_req()
	local data = {reconnect_req={
 		tableid=self.tableid, 		
	}}
	self.network:send(data)
end
function Logic:reconnect_res(data)
	self:print("#####reconnect_res#####",data)
end

--请求桌子状态
function Logic:statusReq()
	local data = {phz_status_req={
		tableid = self.tableid,
		ready=true,	
	}}
	print("______phz_status_req__",data)
	self.network:send(data)
end
function Logic:phz_status_res(data)
	self:print("phz_status_res___",data)
	if not self:showError(data) then 
		return 
	end	
	for k,v in pairs(data.chara_info) do 
		if v.playerid == self.playerid then 
			self.player = v
			self.seatid = v.seatid
			-- self.ai:setSeatid(self.seatid)
			break
		end
	end
	
	self.config = data.room_info
	-- self:sitdownReq()
end

function Logic:sitdownReq()
	local data = {sitdown_req={
		tableid = self.tableid,
	}}
	self.network:send(data)
end
function Logic:sitdown_res(data)
	self:print("__sitdown_res__",data)
	if data.seatid then 
		self.seatid = data.seatid
	end
end
function Logic:standup_res(data)
	self:print("__standup_res__",data)

end


--休息
function Logic:phz_nt_rest(data)

	-- if self.onlineTime > self.ExitTime then 
	-- 	self:exit()
	-- 	return
	-- end			
	-- if self.onlineTime > self.leaveTableTime then 
	-- 	-- self:print("___onlineTime________________",self.onlineTime , self.leaveTableTime)
	-- 	self.leaveTableTime = self.leaveTableTime + self.onlineTime
	-- 	skynet.sleep(math.random(100,200))
	-- 	local randNum = math.random(1,3)		
	-- 	if randNum == 2 then 
	-- 		self:leaveTableReq()
	-- 		return 
	-- 	else		
	-- 	end				
	-- end
	self.myDealCard = {}
	self.curCards = nil
	self.cardSeatid = nil
end

--离开桌子
function Logic:leaveTableReq()
	local data = {
	leave_table_req = {
			tableid = self.tableid,
		}
	}
	self.network:send(data)
end
function Logic:leave_table_res(data)
	self:print("__________ leave_table_res",data)
	if not self:showError(data) then 
		return 
	end
	-- skynet.sleep(math.random(100,500))
	-- --进入场次
	-- self:enterTable(self.roomConf.id)
end

--开始游戏
function Logic:phz_nt_start(data)
	self:print("___phz_nt_start___",self.seatid,data)
	-- if self.playerid == data.playerid then
		self.cards = data.cards
		self:arrange_set(self.cards)
	-- end

end
function Logic:phz_nt_oper(data)
	print("___phz_nt_oper___",data,self.seatid)
	if data.cur_oper and data.cur_oper.seatid == self.seatid then
		if data.cur_oper.button_list and data.cur_oper.button_list[1] == 3 then 
			--不能出牌
			skynet.fork(function()
				skynet.sleep(100)
				local data = {
					phz_next_req={
						tableid = self.tableid,			
					}
				}
				self.network:send(data)	
			end)
			return
		end

		if data.card_seat then 
			self.cardSeatid = data.card_seat
		end
		if data.cards then 
			self.curCards = data.cards
		end
		local data = {
			phz_tip_req={
				tableid = self.tableid,			
			}
		}
		self.network:send(data)	
	end
end

--结束
function Logic:phz_nt_end(data)
	self:print("____phz_nt_end__",data)
	-- if self.playerid ~= self.printPlayerId then 
	-- skynet.fork(function ()
	-- 	skynet.sleep(math.random(200,500))
	-- 	local data = {
	-- 		phz_ready_req={
	-- 			tableid = self.tableid,			
	-- 		}
	-- 	}
	-- 	self.network:send(data)			
	-- end)


		-- --关桌子请求
		-- local data = {
		-- 	phz_close_vote_req={
		-- 		tableid = self.tableid,		
		-- 	}
		-- }
		-- self.network:send(data)		
end


--换桌
function Logic:changetable_req()
	local data = {
		changetable_req={tableid = self.tableid}
	}
	self.network:send(data)
end
function Logic:changetable_res(data)

end

--座位发生改变
function Logic:phz_nt_seat_change(data)
	print("phz_nt_seat_change",data)

end

--个人属性改变
function Logic:nt_goods_change()
	
end


function Logic:phz_deal_res(data)
	print("___phz_deal_res___",data)
	if not data.succese then 
		
	end
end

function Logic:phz_tip_res(data)
	print("___phz_tip_res___",data)
	
	if data.cards and next(data.cards) then
		-- self:print("_______data.cards__",data.cards) 
		local tbCard = {}
		local cards
		for k,v in pairs(data.players) do 
			tbCard[v.seatid] = v.card_data
		end
		self.ai:setCard(tbCard)
		if self.cardSeatid == self.seatid then 
			cards = self.ai:getPutCard()
		else			
			cards = self.ai:getPutCard(self.curCards)
		end
		if not cards then 
			cards = data.cards
		end
		skynet.fork(function()
			skynet.sleep(math.random(100,400))
			local data = {
				phz_deal_req={
					tableid = self.tableid,
					-- cards = data.cards,
					cards = cards,
				}
			}
			self.network:send(data)	
		end)


		local data = {
			phz_jipai_req= {
				tableid = self.tableid,
				-- seatid = self.seatid,		
			}
		}
		-- self.network:send(data)		
	else		

		skynet.fork(function()
			skynet.sleep(math.random(200,500))
			local data = {
				phz_next_req={
					tableid = self.tableid,			
				}
			}
			self.network:send(data)	
		end)
			
	end
end
function Logic:phz_next_res(data)
	self:print("___phz_next_res___",data)
end


function Logic:nt_broadcast(data)
end

function Logic:phz_nt_zhadan(data)
	self:print("___phz_nt_zhadan___",data)
end

function Logic:nt_chat(data)
	self:print("___nt_chat___",data)
end

function Logic:nt_kick_table(data)
	--被踢出房间
	print("____被踢出房间__",self.playerid)
	skynet.exit()
end

function Logic:phz_ready_res(data)
end

function Logic:phz_nt_turn_seat(data)
	self:print("___phz_nt_turn_seat_",data,self.seatid)
	if data.seatid == self.seatid then 		
		skynet.fork(function()
			skynet.sleep(200)
			print("____1111111__________",self.cards)
			local data = {
				phz_deal_req = {
					tableid = self.tableid,
					card = self.cards[1],
				}
			}
			print("___",data)
			self.network:send(data)			
		end)
		
	end

end
function Logic:phz_nt_ti(data)
	print("_____phz_nt_ti_______",data)
	if self.seatid == data.seatid then 
		for i=1,3 do 
			self:drop(self.cards,data.cards[1])
		end
	end
end
function Logic:phz_nt_wei(data)
	print("_____phz_nt_wei_______",data)
	if self.seatid == data.seatid then 
		for i=1,2 do 
			self:drop(self.cards,data.cards[1])
		end
	end
end

function Logic:phz_nt_chi(data)
	print("_____phz_nt_chi_______",data)
	if self.seatid == data.seatid then 
		table.insert(self.cards,self.curCard)
		local cards = data.cards 
		local comp
		if data.comp and next(data.comp) then 
			comp = data.comp[1]
		end
		for k,v in pairs(cards) do
			self:drop(self.cards,v)
		end	
		if comp then 
			for k,v in pairs(comp.cards) do
				self:drop(self.cards,v)
			end				
		end
	end
end

function Logic:phz_nt_peng(data)
	print("_______phz_nt_peng__",data)
	if data.seatid == self.seatid then 
		self:drop(self.cards,data.cards[1])
		self:drop(self.cards,data.cards[1])
	end
end
function Logic:phz_nt_pao(data)
	print("_______phz_nt_pao__",data)
	if data.seatid == self.seatid then 
		-- self:drop(self.cards,data.cards[1])
	end	
end


function Logic:phz_nt_play_card(data)
	print("_______phz_nt_play_card__",data)
	self.curCard = data.card
	if data.seatid == self.seatid then 
		self:drop(self.cards,data.card)
	end
end

function Logic:phz_nt_can_reponse(data)
	print("_______phz_nt_can_reponse__",self.seatid,data)
	--
	if data.chi or data.peng or data.hu then 
		local sendData = {
			phz_next_req = {
				tableid = self.tableid,
			}
		}
		if data.peng then 
			sendData = {
				phz_peng_req = {
					tableid = self.tableid,
					card = data.card,
				}
			}
		elseif 	data.chi then 
			local comp
			if data.chi_info[1] and data.chi_info[1].comp  then
				comp=data.chi_info[1].comp
			end
			sendData = {
				phz_chi_req = {
					tableid = self.tableid,
					cards = data.chi_info[1].cards,
					comp = comp,
				}
			}
		end

		if data.hu then
			sendData = {
				phz_hu_req = {
					tableid = self.tableid,
				}
			}

		end
		skynet.fork(function ( ... )
			skynet.sleep(100)
			print("_____send__",sendData)
			self.network:send(sendData)
		end)
		
	end	
		
end

function Logic:phz_nt_take_card(data)
	print("_______phz_nt_take_card__",data)
	self.curCard = data.card
end
function Logic:phz_nt_confirm_card(data)
	print("_______phz_nt_confirm_card__",data)
end

function Logic:phz_peng_res(data)
	print("_______phz_peng_res__",data)
end
function Logic:phz_chi_res(data)
	print("_______phz_chi_res__",data)
end




function Logic:enterprivate_res(data)
	print("__enterprivate_res__",data)

	if data.tableid > 0 then 
		self.tableid = data.tableid
		self:statusReq()
	end
end
function Logic:createtable_res(data)
	print("__createtable_res__",data)
	local data = {enterprivate_req={tablenum=data.tablenum,gameid=4}}
	self.network:send(data)

	skynet.fork(function()
		skynet.sleep(200)
		self:leaveTableReq()
	end)
end
function Logic:phz_nt_fanka_end(data)
	print("__phz_nt_fanka_end__",data)

end



function Logic:sendHeart()
	local data = {
		heart_req={
			tick = os.time(),			
		}
	}
	self.network:send(data)	
end
function Logic:heart_res(data)
	
end

function Logic:closeByTime()
	--3 - 10分钟后退出游戏
	skynet.fork(function ()
		while (true) do 
			skynet.sleep(500)
			self.onlineTime = self.onlineTime + 1
			self:sendHeart()
		end
	end)
end

function Logic:phz_nt_close_vote(data)
	print("____phz_nt_close_vote__",data)
end

function Logic:phz_close_vote_res(data)
	print("____phz_close_vote_res__",data)	
end


function Logic:nt_manager_close(data)
	print("____nt_manager_close__",data)	
end

function Logic:drop(t,c)
	for i,v in ipairs(t) do
		if v == c then
			table.remove(t,i)
			return true
		end
	end
end






return Logic